/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SMART_SERVE_SERVICES_SERVER_MODEL_MODEL_H
#define SMART_SERVE_SERVICES_SERVER_MODEL_MODEL_H

#include "assertion.h"
#include "model/adapter.h"
#include "model/res_config.h"
#include "scheduler/event.h"
#include <mutex>
#include <atomic>
#include <cstddef>
#include <set>

namespace OHOS {
namespace SmartServe {

class Session;

class Model {
public:
    Model(std::unique_ptr<ModelAdapter> adapter) : adapter_(std::move(adapter))
    {
        resConfigs_ = adapter_->InitialResConfigs();
    }

    // 终止

    void AsyncTerminate() // 无需加锁
    {
        terminating_ = true;
    }

    void WaitForTerminated() // 无需加锁
    {
        ASSERT(terminating_ && "Must call `AsyncTerminate` before `WaitForTerminated`");
        adapter_->Finalize();
    }

    std::atomic_bool terminating_{false}; // 无需加锁

    // 管理结构

    bool AddSession(Session* session) // 要求加管理锁
    {
        return sessions_.insert(session).second;
    }

    bool RemoveSession(Session* session) // 要求加管理锁
    {
        return sessions_.erase(session) != 0;
    }

    std::set<Session*> sessions_; // 要求加管理锁

    // 信息查询

    const std::string& Name() const // 无需加锁
    {
        return adapter_->Name();
    }

    ModelAdapter* Adapter() const // 无需加锁
    {
        return adapter_.get();
    }

    // 对 Scheduler 接口

    // ----- mutex_ 保护区 -----
    std::mutex mutex_;
    std::atomic_bool pending_{false};
    ModelResConfig currentResConfig_;
    ModelResConfig pendingResConfig_;
    // ----- mutex_ 保护区 -----

    ModelResConfig conservativeResConfig();  // 要求加 Model 锁
    std::vector<ModelResConfig> resConfigs_; // 无须加锁，整个生命周期不变

    bool isRunnable() const; // 无须加锁

    void TriggerPending(const ModelResConfig& newResConfig); // 无须加锁
    void TriggerTerminating();                               // 要求加管理锁

private:
    void HandlePending();
    void FinishPendingUse(const ModelApplyResult& result);

    std::unique_ptr<ModelAdapter> adapter_;
};

} // namespace SmartServe
} // namespace OHOS

#endif // SMART_SERVE_SERVICES_SERVER_MODEL_MODEL_H
